package com.cupdata.zicon.jdk7concurrent.chapter1;

import java.util.Random;

/**
 * When an uncaught exception is thrown in Thread, the JVM looks for three possible handlers
for this exception.

First, it looks for the uncaught exception handler of the thread, as was explained in the
Processing uncontrolled exceptions in a Thread recipe. If this handler doesn't exist, then the
JVM looks for the uncaught exception handler for the ThreadGroup class of the thread, as
we learned in this recipe. If this method doesn't exist, the JVM looks for the default uncaught
exception handler, as was explained in the Processing uncontrolled exceptions in a
Thread recipe.
If none of the handlers exit, the JVM writes the stack trace of the exception in the console
and exits the program.

 * @author SunYabing
 *
 */
public class ThreadGroupUncheckExceptionTest {

	//@Test
	public static void  main(String[] args) {
		MyThreadGroup threadGroup = new MyThreadGroup("MyThreadGroup");
		Task123456 task = new Task123456();

		for (int i = 0; i < 2; i++) {
			Thread t = new Thread(threadGroup, task);
			t.start();
		}
	}

}

class MyThreadGroup extends ThreadGroup {

	public MyThreadGroup(String name) {
		super(name);
	}

	@Override
	public void uncaughtException(Thread t, Throwable e) {
		System.out.printf("The thread %s has thrown an Exception\n", t.getId());
		e.printStackTrace(System.out);
		System.out.printf("Terminating the rest of the Threads\n");
		interrupt();
	}
}

class Task123456 implements Runnable {

	@Override
	public void run() {
		int result;
		Random random = new Random(Thread.currentThread().getId());
		while (true) {
			result = 1000 / ((int) (random.nextDouble() * 1000));
			System.out.printf("%s : %f\n", Thread.currentThread().getId(),
					result);
			if (Thread.currentThread().isInterrupted()) {
				System.out.printf("%d : Interrupted\n", Thread.currentThread()
						.getId());
				return;
			}
		}

	}

}
